package com.jandan.persistence.sqlmapdao;

import java.util.Date;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.jandan.ui.client.util.ClientUtil;
import com.jandan.ui.model.CnAndSentence;
import com.jandan.ui.model.LearnedWord;


/**
 * LearnedWordDao接口实现类，使用Ibatis框架进行持久化
 * @author Gong Yong
 * @version 1.0
 * @see com.jandan.persistence.iface.LearnedWordDao
 */
public class LearnedWordSqlMapDao extends SqlMapClientDaoSupport implements
		com.jandan.persistence.iface.LearnedWordDao {
	private final static int NONUSERID = 0;
	private final static int NONWORDLIBID = 0;

	public List<LearnedWord> getLearnedWordListOfOneSmallLibByLessonID(
			long lessonID, long wordLibID, int offset, int limit) {
		// TODO Auto-generated method stub
		Map map = this.getArgumentMapWithOffset(lessonID, NONUSERID, wordLibID,
				offset, limit);

		List<LearnedWord> learnedWordList = this
				.getSqlMapClientTemplate()
				.queryForList(
						"LearnedWord.getLearnedWordListOfOneSmallLibByLessonID",
						map);
		generateCnAndSentence(learnedWordList);
		return learnedWordList;
	}

	public List<LearnedWord> getLearnedWordListOfOneSmallLibByLessonID(
			long lessonID, long wordLibID, int offset, int limit, int start,
			int count) {
		// TODO Auto-generated method stub
		Map map = this.getArgumentMapWithOffset(lessonID, NONUSERID, wordLibID,
				offset, limit);
		List<LearnedWord> learnedWordList = this
				.getSqlMapClientTemplate()
				.queryForList(
						"LearnedWord.getLearnedWordListOfOneSmallLibByLessonID",
						map, start, count);
		generateCnAndSentence(learnedWordList);
		return learnedWordList;
	}

	public LearnedWord getLearnedWordByLearnedWordID(String learnedWordID) {
		// TODO Auto-generated method stub
		LearnedWord lw = (LearnedWord) this.getSqlMapClientTemplate()
				.queryForObject("LearnedWord.getLearnedWordByLearnedWordID",
						learnedWordID);
		if (lw != null) {
			lw.getWord().setCnAndSentenceList(
					this.getCnAndSentenceList(lw.getWordID()));
		}
		return lw;
	}

	public List<LearnedWord> getLearnedWordListByLessonID(long lessonID) {
		// TODO Auto-generated method stub
		List<LearnedWord> learnedWordList = this.getSqlMapClientTemplate()
				.queryForList("LearnedWord.getLearnedWordListByLessonID",
						Long.valueOf(lessonID));
		generateCnAndSentence(learnedWordList);
		return learnedWordList;
	}

	public void insertLearnedWord(LearnedWord learnedWord) {
		// TODO Auto-generated method stub
		this.getSqlMapClientTemplate().insert("LearnedWord.insertLearnedWord",
				learnedWord);
		// return
		// (Long)getSqlMapClientTemplate().queryForObject("LearnedWord.lastInsertLearnedWordID");
	}

	public void updateLearnedWord(LearnedWord learnedWord) {
		// TODO Auto-generated method stub
		this.getSqlMapClientTemplate().update("LearnedWord.updateLearnedWord",
				learnedWord);
	}

	public void deleteLearnedWord(String learnedWordID) {
		// TODO Auto-generated method stub
		this.getSqlMapClientTemplate().delete("LearnedWord.deleteLearnedWord",
				learnedWordID);
	}

	public void insertOrUpdateLearnedWord(LearnedWord learnedWord) {
		// TODO Auto-generated method stub
		if (learnedWord != null) {
			LearnedWord w = this.getLearnedWordByLearnedWordID(learnedWord
					.getLearnedWordID());
			if (w == null) {
				this.insertLearnedWord(learnedWord);
			} else {
				this.updateLearnedWord(learnedWord);
			}
		}
	}

	public int getLearnedWordCountOfOneSmallLibByLessonID(long lessonID,
			long wordLibID, int offset, int limit) {
		// TODO Auto-generated method stub
		Map map = this.getArgumentMapWithOffset(lessonID, NONUSERID, wordLibID,
				offset, limit);

		return (Integer) this.getSqlMapClientTemplate().queryForObject(
				"LearnedWord.getLearnedWordCountOfOneSmallLibByLessonID", map);
	}

	public List<LearnedWord> getAllLearnedStrangeWordListByUserID(long userID) {
		// TODO Auto-generated method stub
		Map map = this.getArgumentMapWithoutOffset(ClientUtil.STRANGE_LESSON_ID, userID, NONWORDLIBID);

		List<LearnedWord> learnedWordList = this
				.getSqlMapClientTemplate()
				.queryForList(
						"LearnedWord.getAllLearnedStrangeWordListByUserID", map);
		generateCnAndSentence(learnedWordList);
		return learnedWordList;
	}

	public List<LearnedWord> getLearnedStrangeWordListByUserID(long userID,
			int offset, int limit) {
		// TODO Auto-generated method stub
		Map map = this.getArgumentMapWithOffset(ClientUtil.STRANGE_LESSON_ID,
				userID, NONWORDLIBID, offset, limit);
		List<LearnedWord> learnedWordList = this
				.getSqlMapClientTemplate()
				.queryForList(
						"LearnedWord.getLearnedStrangeWordListOfOneGroupByUserID",
						map);

		generateCnAndSentence(learnedWordList);

		return learnedWordList;
	}

	public List<LearnedWord> getLearnedWordListByLessonIDAndDate(long lessonID,
			Date date) {
		// TODO Auto-generated method stub
		Map map = this.getArgumentMapWithoutOffset(lessonID, NONUSERID,
				NONWORDLIBID);
		map.put("date", date);
		List<LearnedWord> learnedWordList = this.getSqlMapClientTemplate()
				.queryForList(
						"LearnedWord.getLearnedWordListByLessonIDAndDate", map);

		generateCnAndSentence(learnedWordList);
		return learnedWordList;
	}

	private void generateCnAndSentence(List<LearnedWord> learnedWordList) {
		LearnedWord lw = null;
		for (Iterator<LearnedWord> it = learnedWordList.iterator(); it
				.hasNext();) {
			lw = it.next();
			lw.getWord().setCnAndSentenceList(
					this.getCnAndSentenceList(lw.getWordID()));
		}
	}

	private List<CnAndSentence> getCnAndSentenceList(long wordID) {
		return this.getSqlMapClientTemplate().queryForList(
				"Word.getCnAndSentenceListByWordID", wordID);
	}

	private Map getArgumentMapWithoutOffset(long lessonID, long userID,
			long wordLibID) {
		Map map = new HashMap();
		if (lessonID > 0) {
			map.put("lessonID", lessonID);
		}
		if (userID > 0) {
			map.put("userID", userID);
		}
		if (wordLibID > 0) {
			map.put("wordLibID", wordLibID);
		}

		return map;
	}

	private Map getArgumentMapWithOffset(long lessonID, long userID,
			long wordLibID, int offset, int limit) {
		Map map = this.getArgumentMapWithoutOffset(lessonID, userID, wordLibID);
		map.put("offset", offset);
		map.put("limit", limit);

		return map;
	}
}
